package main

import (
	"fmt"
	"net"
	"os"
	"time"

	"github.com/masx200/http-proxy-go-server/dnscache"
)

func main() {
	fmt.Println("=== DNS缓存混合持久化最终测试 ===")

	// 清理旧文件
	os.Remove("final_dns_cache.json")
	os.Remove("final_dns_cache.aof")

	// 创建生产级配置
	config := dnscache.DefaultConfig()
	config.FilePath = "./final_dns_cache.json"
	config.AOFPath = "./final_dns_cache.aof"
	config.SaveInterval = 30 * time.Second // 30秒全量保存
	config.AOFInterval = 1 * time.Second   // 1秒增量保存

	fmt.Printf("配置:\n")
	fmt.Printf("- 全量保存间隔: %v\n", config.SaveInterval)
	fmt.Printf("- 增量保存间隔: %v\n", config.AOFInterval)
	fmt.Printf("- 快照文件: %s\n", config.FilePath)
	fmt.Printf("- AOF文件: %s\n", config.AOFPath)

	// 第一阶段: 创建缓存并添加数据
	fmt.Println("\n=== 阶段1: 创建缓存并添加数据 ===")
	cache, err := dnscache.NewWithConfig(config)
	if err != nil {
		fmt.Printf("创建DNS缓存失败: %v\n", err)
		return
	}

	// 添加测试数据
	testData := []struct {
		domain string
		ip     string
		ttl    time.Duration
	}{
		{"www.google.com", "142.250.191.14", 10 * time.Minute},
		{"www.github.com", "140.82.112.4", 15 * time.Minute},
		{"api.example.com", "93.184.216.34", 5 * time.Minute},
		{"test.local", "127.0.0.1", time.Hour},
	}

	for _, data := range testData {
		ip := net.ParseIP(data.ip)
		cache.SetIP("A", data.domain, ip, data.ttl)
		fmt.Printf("✓ 添加: %s -> %s (TTL: %v)\n", data.domain, data.ip, data.ttl)
	}

	// 验证数据
	fmt.Println("\n=== 验证数据写入 ===")
	for _, data := range testData {
		if ip, found := cache.GetIP("A", data.domain); found {
			fmt.Printf("✓ 读取: %s -> %s\n", data.domain, ip.String())
		} else {
			fmt.Printf("✗ 未找到: %s\n", data.domain)
		}
	}

	// 等待AOF写入
	time.Sleep(3 * time.Second)

	// 删除一个记录，测试DELETE操作
	fmt.Println("\n=== 测试删除操作 ===")
	cache.Delete("A", "test.local")
	fmt.Printf("✓ 删除: test.local\n")

	time.Sleep(2 * time.Second)

	// 第二阶段: 模拟进程重启，测试数据恢复
	fmt.Println("\n=== 阶段2: 模拟进程重启，测试数据恢复 ===")
	fmt.Println("关闭缓存实例...")
	cache.Close()

	time.Sleep(1 * time.Second)

	fmt.Println("重新创建缓存实例...")
	cache2, err := dnscache.NewWithConfig(config)
	if err != nil {
		fmt.Printf("创建新缓存实例失败: %v\n", err)
		return
	}
	defer cache2.Close()

	// 验证恢复的数据
	fmt.Println("\n=== 验证数据恢复 ===")
	expectedData := testData[:3] // 期望存在的数据（不包括被删除的test.local）
	successCount := 0

	for _, data := range expectedData {
		if ip, found := cache2.GetIP("A", data.domain); found {
			fmt.Printf("✓ 恢复: %s -> %s\n", data.domain, ip.String())
			successCount++
		} else {
			fmt.Printf("✗ 恢复失败: %s\n", data.domain)
		}
	}

	// 验证被删除的数据确实不存在
	if _, found := cache2.GetIP("A", "test.local"); !found {
		fmt.Printf("✓ 正确: test.local 已被删除\n")
		successCount++
	} else {
		fmt.Printf("✗ 错误: test.local 仍然存在\n")
	}

	// 第三阶段: 等待30秒进行全量保存测试
	fmt.Println("\n=== 阶段3: 等待30秒全量保存测试 ===")
	fmt.Println("等待35秒进行全量保存...")

	// 添加一些新数据
	for i := 0; i < 5; i++ {
		domain := fmt.Sprintf("new%d.test.com", i)
		ip := net.ParseIP(fmt.Sprintf("192.168.%d.%d", i/255+1, i%255+1))
		cache2.SetIP("A", domain, ip, 2*time.Minute)
		fmt.Printf("✓ 新增: %s -> %s\n", domain, ip.String())
		time.Sleep(500 * time.Millisecond)
	}

	// 等待30秒进行全量保存
	time.Sleep(35 * time.Second)

	// 第四阶段: 验证全量保存和增量保存的文件
	fmt.Println("\n=== 阶段4: 验证持久化文件 ===")

	// 检查文件大小
	if info, err := os.Stat(config.FilePath); err == nil {
		fmt.Printf("✓ 快照文件存在，大小: %d bytes\n", info.Size())
	}

	if info, err := os.Stat(config.AOFPath); err == nil {
		fmt.Printf("✓ AOF文件存在，大小: %d bytes\n", info.Size())
	}

	// 再次重启，验证混合持久化
	fmt.Println("\n=== 再次重启，验证混合持久化 ===")
	cache2.Close()
	time.Sleep(1 * time.Second)

	cache3, err := dnscache.NewWithConfig(config)
	if err != nil {
		fmt.Printf("创建最终缓存实例失败: %v\n", err)
		return
	}
	defer cache3.Close()

	// 验证所有数据都正确恢复
	totalExpected := len(expectedData) + 5 // 原有数据 + 新增数据
	totalFound := 0

	fmt.Println("验证恢复的数据:")

	// 验证原有数据
	for _, data := range expectedData {
		if ip, found := cache3.GetIP("A", data.domain); found {
			fmt.Printf("✓ %s -> %s\n", data.domain, ip.String())
			totalFound++
		}
	}

	// 验证新增数据
	for i := 0; i < 5; i++ {
		domain := fmt.Sprintf("new%d.test.com", i)
		if ip, found := cache3.GetIP("A", domain); found {
			fmt.Printf("✓ %s -> %s\n", domain, ip.String())
			totalFound++
		}
	}

	// 最终统计
	stats := cache3.Stats()
	fmt.Printf("\n=== 最终统计 ===\n")
	fmt.Printf("期望记录数: %d\n", totalExpected)
	fmt.Printf("实际恢复数: %d\n", totalFound)
	fmt.Printf("缓存项数量: %v\n", stats["item_count"])
	fmt.Printf("恢复成功率: %.1f%%\n", float64(totalFound)/float64(totalExpected)*100)

	if totalFound == totalExpected {
		fmt.Println("\n🎉 所有测试通过！30秒全量保存 + 每秒增量保存功能完美工作！")
	} else {
		fmt.Printf("\n❌ 测试部分失败，恢复率: %.1f%%\n", float64(totalFound)/float64(totalExpected)*100)
	}

	fmt.Println("\n=== 功能总结 ===")
	fmt.Println("✅ 30秒全量保存功能正常")
	fmt.Println("✅ 每秒增量保存功能正常")
	fmt.Println("✅ JSONL格式的AOF日志正常")
	fmt.Println("✅ 数据恢复和重放功能正常")
	fmt.Println("✅ 删除操作持久化正常")
	fmt.Println("✅ 混合持久化策略完美工作")
}
